// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package com.wlit;

import com.formdev.flatlaf.FlatLightLaf;
import com.wlit.httpserver.HttpServer;
import com.wlit.print.LabelPrinter;
import com.wlit.print.LabelPrintDataHandler;
import com.wlit.print.PrintConfig;
import com.wlit.tianping.IDataListener;
import com.wlit.tianping.TianpingConfig;
import com.wlit.tianping.TianpingService;
import com.wlit.ui.MenuHandler;
import com.wlit.ui.TianpingDataHandler;
import com.wlit.ui.resources.Resources;
import com.wlit.websocket.WebSocketServer;
import me.friwi.jcefmaven.CefAppBuilder;
import me.friwi.jcefmaven.CefInitializationException;
import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
import me.friwi.jcefmaven.UnsupportedPlatformException;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefMessageRouter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 应用启动类
 */
public class WlitBrowserApp extends JFrame {
    private static final long serialVersionUID = -5570653778104813836L;

    private final CefApp cefApp;

    public static JFrame mainFrame;

    private CefBrowser browser;

    public static List<IDataListener> dataListeners = new ArrayList<>();


    private WlitBrowserApp(String[] args) throws UnsupportedPlatformException, CefInitializationException, IOException, InterruptedException {
        FlatLightLaf.setup();
        //初始化下天平相关的配置
        TianpingConfig.getInstance().init();
        String comName =  TianpingConfig.getInstance().getComName();
        if (comName != null && !comName.isEmpty()){
            //自动读取并启动串口
            SwingUtilities.invokeLater(()->{
                        TianpingService.getInstance().openComm(comName);
                    }
            );
        }
        //初始化下打印相关的配置
        PrintConfig.getInstance().init();
        String comPrint = PrintConfig.getInstance().getComName();
        if (comPrint != null && !comPrint.isEmpty()){
            //自动读取并启动打印机
            SwingUtilities.invokeLater(() -> {
                LabelPrinter.getInstance().AddCallback();
                LabelPrinter.getInstance().open(comPrint);
            });
        }

        //new WebSocketServer().start();
        new HttpServer().start();

        CefAppBuilder builder = new CefAppBuilder();
        //设置华为镜像，加载比较快
        builder.setMirrors(Arrays.asList("http://mirrors.huaweicloud.com/repository/maven/me/friwi/jcef-natives-{platform}/{tag}/jcef-natives-{platform}-{tag}.jar"));
        // 关闭离屏模式
        builder.getCefSettings().windowless_rendering_enabled = false;

        builder.setAppHandler(new MavenCefAppHandlerAdapter() {
            @Override
            public void stateHasChanged(org.cef.CefApp.CefAppState state) {
                // 窗口关闭的时候 退出
                if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
            }
        });

        String[] params = {"--disable-web-security"};
        builder.addJcefArgs(params);

        cefApp = builder.build();
        //String url = "http://192.168.0.215:8990/#/";
        String url = "https://www.deepseek.com/";
        if (args.length > 0){
            url = args[0];
        }
        final String urlStr = url;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                initAndDisplayUI(urlStr);
            }
        });
        mainFrame = this;
        //启动天平的Api服务
//        TianpingServer tianpingServer = new TianpingServer();
//        tianpingServer.start();
    }

    public static void main(String[] args) {
        try {
            new WlitBrowserApp(args);
        }catch (UnsupportedPlatformException e){
            e.printStackTrace();
        }catch (CefInitializationException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }catch (InterruptedException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void initAndDisplayUI(String url) {
        CefClient client = cefApp.createClient();
        browser = client.createBrowser(url, false, false);

        client.addContextMenuHandler(new MenuHandler(browser));
        //注意JavaScript
        injectJavaScript(client);
        injectPrintJavaScript(client);


        this.setTitle("为乐操作台");
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            @SuppressWarnings("CallToSystemExit")
            @Override
            public void windowClosing(WindowEvent e) {
                if(TianpingService.getInstance().isOpen()){
                    TianpingService.getInstance().closeComm();
                }
                LabelPrinter.getInstance().close();
                CefApp.getInstance().dispose();
                dispose();
            }
        });
        getContentPane().add(browser.getUIComponent(), BorderLayout.CENTER);
        //实现默认全屏
//        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//        ge.getDefaultScreenDevice().setFullScreenWindow(this);

        this.setUndecorated(true);
        this.pack();
        this.setSize(1024, 700);
        this.setLocationRelativeTo(null);
        this.setIconImage(Resources.getIcon("browser16x16.png").getImage());

        this.setExtendedState(JFrame.MAXIMIZED_BOTH); //最大化
        //this.setAlwaysOnTop(true); //总在最前面

        this.setVisible(true);

    }


    private void injectJavaScript(CefClient client){
        CefMessageRouter.CefMessageRouterConfig config = new CefMessageRouter.CefMessageRouterConfig("tianping","tianpingCancel");
        CefMessageRouter msgRouter = CefMessageRouter.create(config);
        TianpingDataHandler tianpingDataHandler = new TianpingDataHandler();
        msgRouter.addHandler(tianpingDataHandler,true);

        client.addMessageRouter(msgRouter);
    }

    private void injectPrintJavaScript(CefClient client){
        CefMessageRouter.CefMessageRouterConfig config = new CefMessageRouter.CefMessageRouterConfig("labelprint","labelprintCancel");
        CefMessageRouter msgRouter = CefMessageRouter.create(config);
        LabelPrintDataHandler handler = new LabelPrintDataHandler();
        msgRouter.addHandler(handler,true);

        client.addMessageRouter(msgRouter);
    }


}
